package com.designPattern.observer.dns;

import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.ThreadLocalRandom;

/**
 * dns服务：既是观察者，又是被观察者
 *
 * @author : liutianlong
 * @date : 2023/6/2
 * @since : 1.0
 */
public abstract class DnsServer extends Observable implements Observer {

    /**
     * 收到通知的事件：先判断自己是否能解析，不能解析，则通知上层解析
     * @param o
     * @param arg
     */
    @Override
    public void update(Observable o, Object arg) {
        Recorder recorder = (Recorder) arg;
        boolean local = isLocal(recorder);
        if(local) {
            recorder.setIp(genIpAddress());
        }else {
            this.notifyUpperServer(recorder);
        }
        sign(recorder);
    }

    /**
     * 作为被观察者，允许增加观察者，规定：一个dns只有一个上级
     * @param dnsServer
     */
    public void addUpperServer(DnsServer dnsServer) {
        super.deleteObservers();
        super.addObserver(dnsServer);
    }

    private void notifyUpperServer(Recorder recorder) {
        super.setChanged();
        super.notifyObservers(recorder);
    }

    /**
     * 随机生成一个ip地址
     * @return
     */
    private String genIpAddress() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(ThreadLocalRandom.current().nextInt(255));
        stringBuilder.append(".");
        stringBuilder.append(ThreadLocalRandom.current().nextInt(255));
        stringBuilder.append(".");
        stringBuilder.append(ThreadLocalRandom.current().nextInt(255));
        return stringBuilder.toString();
    }


    /**
     * 对解析记录签名，标记是谁解析的
     * @param recorder
     */
    public abstract void sign(Recorder recorder);

    /**
     * 本服务能否解析
     * @param recorder
     * @return
     */
    public abstract boolean isLocal(Recorder recorder);
}
